#!/sbin/openrc-run
#
# $Header: mkinitramfs-ll/svc/zram.initd                 Exp $
# $Author: (c) 2012-6 tokiclover <tokiclover@gmail.com>  Exp $
# $License: 2-clause/new/simplified BSD                  Exp $
# $Version: 0.22.1 2016/07/20 12:33:03                   Exp $
#

description="Initialize ZRAM devices and filesystems"
description_reset="Reset ZRAM devices"
extra_commands=reset

:	${ZRAM_DEVICE_NUMBER:=4}
:	${NULL=/dev/null}

depend()
{
	before bootmisc
}

start()
{
	local blk_dir cmd dev type mode mnt_dir num=0 offset=0 mnt_opts ret
	local CONTINUE='{ num=$((${num}+1)); continue; }'

	for cmd in mkfs mount mkswap swapon; do
		eval ${cmd}="$(command -v "${cmd}" 2>${NULL})"
	done

	while true; do
		#
		# Find the first free device
		#
		dev=/dev/zram$((${num}+${offset}))
		[ -b ${dev} ] || break
		if [ "$(cat /sys/block/${dev##*/}/size)" != 0 ]; then
			offset=$((${offset}+1)); continue;
		fi
		eval set -- \${ZRAM_DEVICE_${num}}
		size="${1}" type="${2}" mnt_dir="${3}" mnt_opts="${4}" mode="${5}"
		#
		# Initialize device if defined
		#
		blk_dir="/sys/block/${dev##*/}"
		[ -n "${size}" ] || break
		[ -n "${ZRAM_COMPRESSOR}"    ] &&
			echo "${ZRAM_COMPRESSOR}"    >${blk_dir}/comp_algorithm
		[ -n "${ZRAM_STREAM_NUMBER}" ] &&
			echo "${ZRAM_STREAM_NUMBER}" >${blk_dir}/max_comp_streams
		echo "${size}" >${blk_dir}/disksize
		#
		# Setup device if requested
		#
		[ -n "${type}" ] || eval ${CONTINUE}
		case "${type}" in
			(swap)
			ebegin "Activating ${dev} swap device"
			${mkswap} ${dev} >${NULL} 2>&1 &&
			${swapon} ${dev} >${NULL} 2>&1
			eend "${?}"
			;;
			(*)
			ebegin "Formating ${dev} (${type} filesystem)"
			${mkfs} -t ${type} ${dev} >${NULL} 2>&1
			ret="${?}"
			eend "${ret}"

			if [ "${ret}" = 0 ] && [ -n "${mnt_dir}" ]; then
				[ -d "${mnt_dir}" ] || mkdir -p "${mnt_dir}"

				ebegin "Mounting ${dev} to ${mnt_dir}"
				${mount} -t ${type} ${mnt_opts:+-o} ${mnt_opts} ${dev} "${mnt_dir}"
				eend "${?}"
				[ -n "${mode}" ] && chmod ${mode} "${mnt_dir}"
			fi;;
		esac
		eval ${CONTINUE}
	done
	return 0
}

start_pre()
{
	case "${ZRAM_COMPRESSOR}" in
		(lz4|lzo)     ;;
		(*) ZRAM_COMPRESSOR=;;
	esac
	[ -w /sys/block/zram0/comp_algorithm   ] || ZRAM_COMPRESSOR=
	[ -w /sys/block/zram0/max_comp_streams ] || ZRAM_STREAM_NUMBER=

	if grep -qw zram /proc/modules; then
		rmmod zram 2>${NULL} ||
		{ reset && rmmod zram 2>${NULL}; } ||
		{ ewarn "Cannot initialize kernel module"; return; }
	fi
	modprobe zram num_devices=${ZRAM_DEVICE_NUMBER} 2>${NULL} || reset
}

stop()
{
	local dev type mnt_dir num=0
	while true; do
		eval set -- \${ZRAM_DEVICE_${num}}
		type="${2}" mnt_dir="${3}"
		case "${type}" in
			(swap) ;;
			([a-z]*)
			case "${mnt_dir}" in
				(*/run|*/tmp) ;;
				(*)
				if mountinfo -q "${mnt_dir}"; then
					ebegin "Unmounting ${mnt_dir}"
					umount -l "${mnt_dir}" 2>${NULL}
					eend "${?}"
				fi;;
			esac;;
			(*) break;;
		esac
		num=$((${num}+1)); continue;
	done
	return 0
}

reset()
{
	local dev ret=0
	for dev in /dev/zram[0-9]*; do
		if grep -Eqw "${dev}[[:space:]]" /proc/mounts ||
			grep -Eqw "${dev}[[:space:]]" /proc/swaps; then
			ewarn "${dev} device is mounted"
			ret=$((${ret}+1))
			continue
		fi
		echo 1 >/sys/block/${dev##*/}/reset
	done
	return ${ret}
}

restart()
{
	start
}

#
# vim:fenc=utf-8:ft=gentoo-init-d:ci:pi:sts=0:sw=4:ts=4:
#
